<template>
  <div class="my-tooltip" v-on="outerEvents">
    <div class="my-tooltip__trigg" ref="triggerRef" v-on="events">
      <slot></slot>
    </div>
    <div class="my-tooltip__popper" ref="popperRef" v-show="isOpen">
      <slot name="content">
        {{ content }}
      </slot>
      <div id="arrow" data-popper-arrow></div>
    </div>
  </div>
</template>

<script setup name="MyTooltip">
import propObj from './props'
import { ref, watch, reactive, computed } from 'vue'
import { createPopper } from '@popperjs/core'
defineOptions({
  name: 'MyTooltip'
})
const emit = defineEmits(['visible-change'])
const props = defineProps(propObj)
const isOpen = ref(false)
const triggerRef = ref(null)
const popperRef = ref(null)
let popperInstance = null
const events = reactive({})
const outerEvents = reactive({})

const popperOptions = computed(() => {
  return {
    placement: props.placement,
    modifiers: [
      {
        name: 'offset',
        options: {
          offset: [0, 6]
        }
      }
    ]
  }
})
watch(isOpen, (newVal) => {
  if (newVal) {
    if (triggerRef.value && popperRef.value) {
      popperInstance = createPopper(triggerRef.value, popperRef.value, popperOptions.value)
    }
    else {
      popperInstance?.destroy()
    }
  }
}, { flush: 'post' })

let setTimeoutId = null
const open = () => {
  if (props.openDelay) {
    if (setTimeoutId) {
      clearTimeout(setTimeoutId)
    }
    setTimeoutId = setTimeout(() => {
      isOpen.value = true
      emit('visible-change', true)
    }, props.openDelay)
  }
  else {
    isOpen.value = true
    emit('visible-change', true)
  }
}
const close = () => {
  if (props.closeDelay) {
    if (setTimeoutId) {
      clearTimeout(setTimeoutId)
    }
    setTimeoutId = setTimeout(() => {
      isOpen.value = false
      emit('visible-change', false)
    }, props.closeDelay)
  }
  else {
    isOpen.value = false
    emit('visible-change', false)
  }

}
const attachEvents = () => {
  if(props.manual) return
  if (props.trigger === 'hover') {
    events['mouseenter'] = () => {
      open()
    }
    outerEvents['mouseleave'] = () => {
      close()
    }
  }
  else if (props.trigger === 'click') {
    events['click'] = () => {
      if (isOpen.value) {
        close()
      }
      else {
        open()
      }
    }
  }
}
attachEvents()
defineExpose({
  show:open,
  hide:close
})
</script>

<style lang="scss" scoped>

</style>
